﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Qas.CommonLogic.BusinessObjects;
using Qas.CommonLogic;

namespace Qas.User.Keepers
{
    public abstract class AbstractKeeper : IKeeper
    {
        protected Base curBase = null;
        protected double avaiableBudget = 0;
        protected double availableTime = 0;

        /// <summary>
        /// Целевое состояние системы
        /// </summary>
        protected List<Condition> goalState;

        /// <summary>
        /// Начальное состояние системы
        /// </summary>
        protected List<Condition> initialState;

        protected AbstractKeeper(Base currentBase) {
            this.curBase = currentBase;
        }

        public void Analyzer(Plan planToAnalyze, int taskcounter)
        {
            Log.WriteToLog(planToAnalyze);

            Log.WriteToLog(planToAnalyze, taskcounter);
            //for (int i; i < listOfPlans.Count; i++)
            //{
            //    //listOfPlans[]

            //}
        }

        /// <summary>
        /// Проверка на то, покрывает ли задача некоторый список пост-условий
        /// </summary>
        /// <param name="task">Проверяемая задача</param>
        /// <param name="postConditions">Список условий, которые нужно покрыть</param>        
        /// <returns>Ответ на вопрос, покрывает ли задача список пост-условий</returns>
        protected bool TaskCanCover(Task task, List<Condition> postConditions)
        {
            foreach (Condition cond in postConditions)
            {
                if (!task.PostConditions.Contains(cond))
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Проверка возможности выполнения задачи исходя из заданных компетенций
        /// </summary>
        /// <param name="task"></param>
        /// <param name="availableCompetences"></param>
        /// <returns></returns>
        protected bool CanBeDone(Task task, List<Competence> availableCompetences)
        {
            foreach (Competence comp in task.RequiredCompetences)
            {
                if (!availableCompetences.Contains(comp))
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Проверяем, содержится ли первое множество условий во втором
        /// </summary>
        protected bool Contains(List<Condition> first, List<Condition> second)
        {
            foreach (Condition cond in first)
            {
                if (!second.Contains(cond))
                {
                    return false;
                }
            }

            return true;
        }


        protected List<Plan> Union(List<Plan> firstList, List<Plan> secondList)
        {
            if (secondList != null)
            {
                foreach (Plan result in secondList)
                {
                    if (!firstList.Contains(result))
                    {
                        firstList.Add(result);
                    }
                }
            }

            return firstList;
        }

        /// <summary>
        /// Проверка достаточности компетенций для выполнения задачи
        /// </summary>
        public List<Task> FilterByCompetences(List<Competence> availableCompetences, List<Task> tasksToFilter)
        {
            List<Task> goodTasks = new List<Task>();
            foreach (Task task in tasksToFilter)
            {
                if (CanBeDone(task, availableCompetences))
                {
                    goodTasks.Add(task);
                }
            }

            return goodTasks;
        }




        /// <summary>
        /// Проверка, может ли задача быть выполнена в 
        /// контексте определённого набора предусловий;
        /// т.е. множество актуальных предусловий "покрывает"
        /// множество предусловий задачи
        /// </summary>
        /// <param name="preConditions">Текущие предусловия, в 
        /// контексте которых проверяется задача</param>
        /// <param name="task">Проверяемая задача</param>
        /// <returns>True в случае если задача может быть выполнена
        /// и False в противном случае</returns>
        protected bool TaskCanBeStarted(List<Condition> preConditions, Task task)
        {
            foreach (Condition cond in task.PreConditions)
            {
                // Как только обнаружили предусловие данной задачи,
                // которое не входит в число актуальных предусловий,
                // задача не может быть выполнена
                if (!preConditions.Contains(cond))
                    return false;
            }

            // Если неожиданных предусловий не встречено, значит всё круто!
            return true;
        }

        #region IKeeper Members

        public abstract List<Plan> Search(List<Task> tasks, 
            List<Condition> initConditions, List<Condition> goalConditions);

        #endregion
    }
}
